iT邦幫忙

2023 iThome 鐵人賽

DAY 1
0
自我挑戰組

Django系列 第 7

Day7~Django 漫漫長路- 手把手hoding serializers

  • 分享至 

  • xImage
  •  

大家好,我是Leo
今天我來介紹的是django serializers 也會帶操作一些使用上的範例/images/emoticon/emoticon30.gif
OK~~~ Let's go now!!!


serializers 是什麼

序列化器允許把像查詢集和模型實例這樣的複雜數據轉換為可以輕鬆渲染成JSON,XML或其他內容類型的原生Python類型。序列化器還提供反序列化,在驗證傳入的數據之後允許解析數據轉換回複雜類型。

  • 序列化的過程 : database -> model -> JSON/XML等格式

serializers.ModelSerializer

ModelSerializer提供了一個快捷方式,可讓您自動創建一個Serializer,包含與模型字段對應的字段。

ModelSerializer與Serializer不同之處在於:

  • 它會根據模型自動為您生成一組字段。
  • 它會自動為序列化器生成驗證器。
  • .create() 它包括和的簡單默認實現 .update()。

以下是 serializers.ModelSerializer 基本用法
定義一個class Meta並宣告資料要呈現的方式

class UserSerializers(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('username', 'password', 'email', 'tel', 'first_name','last_name')

使用繼承方式篩選欄位

class UserFilterFieldSerializers(UserSerializers):
    class Meta:
        model = User
        fields = ('username', 'password')

增加一個user_role model

https://ithelp.ithome.com.tw/upload/images/20221218/20154853bl0TbIK4jS.jpg

如果今天要找尋Users and Users底下的role name and salary的field data
因為我們上次還未建立user_roles的model 接下來我們會先建立一個model
然後因為上次有註冊的apiview 連同rest-framework serializer的部分也會做修改

serializers/users_ser.py
add new
role = serializers.IntegerField()
role_id=User_Roles.objects.get(id=validated_data['role']).id

class UsersSerializer(serializers.ModelSerializer):
    username = serializers.CharField(
        required=True,
        validators=[UniqueValidator(queryset=User.objects.all())],
    )
    password = serializers.CharField(write_only=True, required=True, validators=[validate_password],)
    email = serializers.EmailField(write_only=True, required=True)

    tel = serializers.CharField(write_only=True, required=False,allow_null=True)
    first_name = serializers.CharField(write_only=True, required=False,allow_null=True)
    last_name = serializers.CharField(write_only=True, required=False,allow_null=True)
    role = serializers.IntegerField()
    class Meta:
        model = User
        fields = ('username', 'password', 'email', 'tel', 'first_name','last_name','role')

    def create(self, validated_data):
        user = User(
            username=validated_data['username'],
            email=validated_data['email'],
            password=validated_data['password'],
            first_name=validated_data['first_name'],
            last_name=validated_data['last_name'],
        )
        user.set_password(validated_data['password']) #加密
        user.save()

        users = Users.objects.create(
            auth_user=user,
            tel=validated_data['tel'],
            role_id=User_Roles.objects.get(id=validated_data['role']).id
        )

        users.save()
        return user

models/users.py
add new
role = models.ForeignKey(User_Roles, on_delete=models.PROTECT, to_field='id', related_name='users',default=None,blank=True,null=True)

from django.contrib.auth.models import User
from django.db import models
from website.models.user_roles_model import User_Roles

class Users(models.Model):
    id =  models.AutoField(primary_key=True)
    auth_user = models.OneToOneField(User, on_delete=models.PROTECT,related_name='users')
    role = models.ForeignKey(User_Roles, on_delete=models.PROTECT, to_field='id', related_name='users',default=None,blank=True,null=True)
    tel = models.CharField(max_length=255, null=True)
    language = models.IntegerField(default=1,null=True) # INT[null, note: '1:繁體中文']
    title = models.CharField(max_length=255,null=True)
    status = models.IntegerField(default=0) # INT[not null, note: '0:待認證 1:啟用 2:停用']
    created_at = models.DateTimeField(auto_now_add = True,editable=False)
    updated_at = models.DateTimeField(auto_now = True)
    deleted_at = models.DateTimeField(null=True)

models/user_roles_model.py

from django.db import models

class User_Roles(models.Model):
    id =  models.AutoField(primary_key=True)
    name = models.CharField(max_length=255)
    salary = models.FloatField()

models/init

from .user_roles_model import *

回到 manage.py層

python .\manage.py makemigrations
python .\manage.py migrate 

執行後會發現在 website/migrations 下面會生成一個 0002_user_roles.py
在database內新生成一個table : user_roles 我們在insert 一些data進去
例如

https://ithelp.ithome.com.tw/upload/images/20221218/20154853G4SzKMjk38.jpg

接下來使用postman 直接透過apiview新增資料入database
https://ithelp.ithome.com.tw/upload/images/20221218/20154853fi1qPou1dl.jpg


users相關資訊呈現

今天如果期望可以看到的資訊分別如下

  • username
  • password
  • email
  • tel
  • role_name
  • role_salary

serializers/users_ser add new
這裡使用ReadOnlyField使用上非常便利
不用管型態為何直接幫你抓型態
source 源自於 "哪個field"."哪個field"
這邊我也可以將field欄位改名 原本是tel -> phone

class UserInformationsRoleSerializer(UsersSerializer):
    username = serializers.ReadOnlyField(source="auth_user.username")
    password = serializers.ReadOnlyField(source='auth_user.password')
    email = serializers.ReadOnlyField(source='auth_user.email')
    phone = serializers.ReadOnlyField(source='tel')
    roleName = serializers.ReadOnlyField(source='role.name')
    roleSalary = serializers.ReadOnlyField(source='role.salary')

    class Meta:
        model = Users
        fields = ('username', 'password', 'email', 'phone', 'roleName','roleSalary')

views/users.py add new
此method 為 get

from ..serializers import UserInformationsRoleSerializer
class UserInformationAPIView(generics.ListAPIView):
    queryset = Users.objects.all()
    serializer_class = UserInformationsRoleSerializer

mysite/urls.py add new

from website.views import UserInformationAPIView
    path('api/users/informations',UserInformationAPIView.as_view(),name='api-informations')

使用postman測試,恭喜您成功了

https://ithelp.ithome.com.tw/upload/images/20221218/20154853gLkPuFs0fL.jpg


今天主要是介紹serializers的概念,及一些使用方式,與如果要更改model時的一些操作流程
我們明天預計會從寫makemigrations 生成資料的方式與回朔功能進行介紹
我們明天見,各位掰掰~~~/images/emoticon/emoticon29.gif


上一篇
Day6~ Django 漫漫長路- 一腳踏入DRF API的領域
下一篇
Day8~Django 漫漫長路- migrations掌握回朔的技巧
系列文
Django30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言